{
"cells": [
{
"cell_type": "markdown",
"id": "agreed-japanese",
"metadata": {},
"source": [
"(ex_viz_linalg)=\n",
"# Visualizing Linear Algebra Decompositions\n",
"\n",
"In this notebook we just demonstrate the utility function ``xyzpy.visualize_matrix`` on\n",
"various linear algebra decompositions taken from ``scipy``. This function plots matrices\n",
"with the values of numbers directly mapped to color. By default, complex phase gives the hue,\n",
"with\n",
"\n",
"* real positive = blue\n",
"* real negative = orange\n",
"* imaginary positive = purple\n",
"* imaginary negative = green\n",
"\n",
"whereas the magnitude gives the saturation, such that $|z| \\sim 0$ gives white."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "occasional-upset",
"metadata": {},
"outputs": [],
"source": [
"%config InlineBackend.figure_formats = ['svg']\n",
"import numpy as np\n",
"import scipy.linalg as sla\n",
"\n",
"import xyzpy as xyz\n",
"\n",
"rng = np.random.default_rng(42)"
]
},
{
"cell_type": "markdown",
"id": "expanded-senegal",
"metadata": {},
"source": [
"First we'll start with a non-symmetric random matrix with some small complex parts:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "rotary-burton",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"X = 0.1 * rng.normal(size=(20, 20)) + 0.01j * rng.normal(size=(20, 20))\n",
"xyz.visualize_matrix(X, figsize=(2, 2));"
]
},
{
"cell_type": "markdown",
"id": "accompanied-moment",
"metadata": {},
"source": [
"## Singular Value Decomposition"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "egyptian-retreat",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"xyz.visualize_matrix(sla.svd(X), figsize=(8, 6));"
]
},
{
"cell_type": "markdown",
"id": "restricted-reasoning",
"metadata": {},
"source": [
"The 1D array of real singular values in decreasing magnitude is shown as a diagonal."
]
},
{
"cell_type": "markdown",
"id": "associate-alexander",
"metadata": {},
"source": [
"## Eigen-decomposition"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "pregnant-accent",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"xyz.visualize_matrix(sla.eig(X), figsize=(6, 4));"
]
},
{
"cell_type": "markdown",
"id": "indie-fireplace",
"metadata": {},
"source": [
"Here we see the introduction of many complex numbers far from the real axis."
]
},
{
"cell_type": "markdown",
"id": "expressed-technician",
"metadata": {},
"source": [
"## Schur decomposition"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "configured-treatment",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"xyz.visualize_matrix(sla.schur(X), figsize=(6, 4));"
]
},
{
"cell_type": "markdown",
"id": "raised-somalia",
"metadata": {},
"source": [
"If you look closely here at the color sequence of the left diagonal\n",
"it follows the eigen decomposition."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "specified-tradition",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"xyz.visualize_matrix(sla.schur(X.real), figsize=(6, 4));"
]
},
{
"cell_type": "markdown",
"id": "published-control",
"metadata": {},
"source": [
"## QR Decomposition"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "satellite-sandwich",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"xyz.visualize_matrix(sla.qr(X), figsize=(6, 4));"
]
},
{
"cell_type": "markdown",
"id": "minute-senator",
"metadata": {},
"source": [
"## Polar Decomposition"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "outside-implement",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"xyz.visualize_matrix(sla.polar(X), figsize=(6, 4));"
]
},
{
"cell_type": "markdown",
"id": "internal-reverse",
"metadata": {},
"source": [
"## LU Decomposition"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "analyzed-partner",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"xyz.visualize_matrix(sla.lu(X), figsize=(8, 6));"
]
},
{
"cell_type": "markdown",
"id": "bottom-sword",
"metadata": {},
"source": [
"Multiplying the left matrix in reorders the rows of the $L$ factor:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "extreme-gibson",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"xyz.visualize_matrix(sla.lu(X, permute_l=True), figsize=(6, 4));"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}